package org.example.config;


import org.apache.commons.lang3.StringUtils;
import org.example.common.LoginUserDetail;
import org.example.common.StatusCode;
import org.example.pojo.entity.SysMenu;
import org.example.pojo.entity.SysUser;
import org.example.pojo.vo.MenuVo;
import org.example.service.SysMenuService;
import org.example.service.SysRoleService;
import org.example.service.SysUserService;
import org.example.service.impl.SysMenuServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static org.example.service.impl.SysMenuServiceImpl.listMenuTree;

/**
 * 自定义实现权限认证
 */
@Service
public class LoginUserDetailsService implements UserDetailsService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysMenuServiceImpl sysMenuServiceImpl;

    @Autowired
    private SysRoleService sysRoleService;


    /**
     * 自定义用户认证
     *
     * @param userName the username identifying the user whose data is required.
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        SysUser sysUser = sysUserService.getByUser(userName);
        if (sysUser == null) {
            throw new UsernameNotFoundException(StatusCode.USER_NOT_EXIST.name());
        }
        //获取用户权限列表数据菜单
        List<SysMenu> userMenuList = sysMenuService.getUserAuthorMenu(sysUser.getUserId(),userName);
        //构建菜单树
        List<MenuVo> userMenuTree = listMenuTree(new ArrayList<>(), userMenuList);
        //获取按钮权限集合 system:user:list
        List<String> permissionList = userMenuList.stream().filter(item -> StringUtils.isNoneBlank(item.getPerms())).map(SysMenu::getPerms).collect(Collectors.toList());
        //获取用户所属角色
        List<Long> roleIds = sysMenuServiceImpl.getUserRoleIds(sysUser.getUserId());
        //获取角色名称
        List<String> roleNameList = sysRoleService.getUSerRoleName(roleIds);
        //构建权限限表示
        for (String roleName : roleNameList) {
            permissionList.add("ROLE_" + roleName);
        }
        //定义权限列表.
        String[] permissionArr = permissionList.toArray(new String[permissionList.size()]);
        List<GrantedAuthority> authoritieList = AuthorityUtils.createAuthorityList(permissionArr);
        //6.封装用户详情信息实体对象
        LoginUserDetail loginUserDetail = new LoginUserDetail(sysUser.getUserName(), sysUser.getPassword(), authoritieList);
        //将用户的id nickname等相同属性信息复制到详情对象中
        BeanUtils.copyProperties(sysUser, loginUserDetail);
        loginUserDetail.setMenus(userMenuTree);
        loginUserDetail.setPermission(permissionList);
        loginUserDetail.setUserId(sysUser.getUserId().toString());
        return loginUserDetail;
    }
}
